
ts1.6 之后支持泛型。泛型：可以是广泛的类型。就是这个变量在声明时不指定类型，使用时再确定类型。  
作用：考虑可重用性。 组件不仅能够支持当前的数据类型，同时也能支持未来的数据类型

## 使用场景
现在有一个对数组排序的需要，如果是number数组进行从小到大排序，如果是字符串数组进行Unicode排序。 那这个数组应该怎么传呢?

你可能会这样写，当然也是可以的，
```ts 
function  arrSort(arr: number[] | string[]) : number[] | string[] { }
```

但如果又增加了一个boolean类型的数组，我们需要将true项全部放到前面，这个类型应该怎么写？
```ts 
function  arrSort(arr: number[] | string[] | boolean[]) : number[] | string[] | boolean[] { }
```

偷个懒，这样写。

```ts 
function  arrSort(arr: any[]) : any[] { }
```


其实像这种，在使用时才能确定类型的场景，我们可以使用泛型。

```ts 
function  arrSort<T>(arr: T[]) : T[] { let array:T[] = []; return array}

arrSort<string>(['张三']);

arrSort(['张三']) // 可省略，会自动推论
```

在< T > 内声明了一个泛型占位符T(字母可随意写)，后面就可以使用这个类型了。
:::tip
``` <T> ``` 是写在（ ）前面。  
常见的占位符含义：  
T  &nbsp;&nbsp;&nbsp;(Type)    类型   
K  &nbsp;&nbsp;&nbsp;(Key)     对象中的键  
V  &nbsp;&nbsp;&nbsp;(Value)   对象中的值  
E  &nbsp;&nbsp;&nbsp;(Element) 元素类型
:::
当然可声明多个泛型。
```ts 
function  arrSort<T, E>(arr: T[]) : E[] { let array:E[] = []; return array}

arrSort<string>(['张三']);

```

## 泛型约束
在函数内部使用泛型变量的时候，由于事先不知道它是哪种类型，所以不能随意的操作它的属性或方法：

```ts
function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);
    return arg;
}

// index.ts(2,19): error TS2339: Property 'length' does not exist on type 'T'.
```

我们可以对泛型进行约束。

```ts 
interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

// 这时如果传入一个数字，数字没有length 属性就会报错
loggingIdentity(7);

// index.ts(10,17): error TS2345: Argument of type '7' is not assignable to parameter of type 'Lengthwise'.

```
[泛型约束案例来自这里](https://ts.xcatliu.com/advanced/generics.html#%E6%B3%9B%E5%9E%8B%E7%BA%A6%E6%9D%9F)

## 在类中使用接口

```ts 
class User<T> {
  name: T;
  constructor(name: T) {
    this.name = name;
  }
  getName(): T {
    return this.name;
  };
}

let createUser = new User<string>('张三');
console.log(createUser.getName());
```